<template>
  <div class="container">
    <el-card>
      <el-form style="width: 80%" :model="ArticleParams" ref="formRef">
        <el-form-item
          label="文章标题"
          label-width="90px"
          label-position="left"
          prop="title"
        >
          <el-input
            placeholder="请您输入文章标题"
            v-model="ArticleParams.title"
          ></el-input>
        </el-form-item>
        <el-form-item
          label="文章封面"
          label-width="90px"
          label-position="left"
          prop="cover_image"
        >
          <!--       el-upload:action属性：图片上传路径   -->
          <!--       el-upload::show-file-list属性：是否显示上传图片列表   -->
          <el-upload
            class="avatar-uploader"
            action="/api/media/admin/fileupload/"
            :show-file-list="false"
            :on-success="handleAvatarSuccess"
            :before-upload="beforeAvatarUpload"
            :on-error="handleAvatarError"
          >
            <img
              v-if="ArticleParams.cover_image"
              :src="ArticleParams.cover_image"
              alt="Logo"
              class="avatar"
              style="max-width: 150px; max-height: 150px"
            />
            <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
          </el-upload>
        </el-form-item>
        <el-form-item
          label="文章分类"
          label-width="90px"
          label-position="left"
          prop="category"
        >
          <el-select
            v-model="ArticleParams.category"
            placeholder="请选择文章分类"
            style="width: 150px"
          >
            <el-option
              v-for="item in categoryData"
              :key="item.id"
              :label="item.name"
              :value="item.id"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item
          label="文章标签"
          label-width="90px"
          label-position="left"
          prop="tags"
        >
          <el-tag
            v-for="tagId in ArticleParams.tags"
            :key="tagId"
            closable
            :disable-transitions="false"
            @close="handleTagClose(tagId)"
            style="margin-right: 5px"
          >
            {{ getTagName(tagId) }}
          </el-tag>
          <el-button
            v-if="is_addTag"
            type="primary"
            icon="Plus"
            @click="handleAddTag"
          ></el-button>
          <el-select
            v-if="!is_addTag"
            style="width: 100px"
            v-model="selectedTag"
            @change="handleTagChange"
          >
            <el-option
              v-for="tag in tagData"
              :key="tag.id"
              :label="tag.name"
              :value="tag.id"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item
          label="设置状态"
          label-width="90px"
          label-position="left"
          prop="status"
        >
          <el-select
            v-model="ArticleParams.status"
            style="width: 100px"
            placeholder="设置文章状态"
          >
            <el-option
              v-for="status in statusOptions"
              :key="status.value"
              :label="status.label"
              :value="status.value"
            ></el-option>
          </el-select>
        </el-form-item>
      </el-form>
      <!--      具名插槽-->
      <!--      <template #footer>-->
      <!--        <el-button type="primary" size="default" @click="confirm">-->
      <!--          确定-->
      <!--        </el-button>-->
      <!--        <el-button type="danger" size="default" @click="cancel">取消</el-button>-->
      <!--      </template>-->
      <div style="height: 80vh; width: 100%">
        <MdEditor
          v-model="ArticleParams.content"
          style="height: 80vh"
          :toolbars="toolbars as []"
          @onUploadImg="onUploadArticleImg"
        />
      </div>
      <div style="display: flex; justify-content: flex-end; margin-top: 20px">
        <el-button type="primary" size="large" @click="handlePulish">
          发布
        </el-button>
      </div>
    </el-card>
  </div>
</template>

<script setup lang="ts">
import 'md-editor-v3/lib/style.css'
import { MdEditor } from 'md-editor-v3'
import { onMounted, reactive, ref } from 'vue'
import { reqUploadImage } from '@/api/image/index.ts'
import { ElMessage, UploadProps } from 'element-plus'
import type { Article } from '@/api/article/type.ts'
import type { Category } from '@/api/category/type.ts'
import { reqHasCategory } from '@/api/category'
import type { TagRecords } from '@/api/tag/type.ts'
import { reqHasTag } from '@/api/tag'
import { reqAddArticle, reqArticle } from '@/api/article'

// 收集表单数据
let ArticleParams = reactive<Article>({
  title: '',
  cover_image: '',
  category: '',
  tags: [],
  status: '0',
  content: '',
})

//控制添加标签或者输入框的展开
let is_addTag = ref<boolean>(true)
// 选中的标签
const selectedTag = ref<number | null>(null)

//存储获取的分类数组
const categoryData = reactive<Category[]>([])
//存储获取的标签数组
const tagData = reactive<TagRecords>([])
//表示状态的数组
const statusOptions = [
  { value: '0', label: '正常' },
  { value: '1', label: '置顶' },
  { value: '2', label: '隐藏' },
]

//组件挂载时获取分类和标签数组
onMounted(async () => {
  const response = await reqHasCategory()
  if (response.code == 200) {
    // 将返回的 data 赋值给 categoryData
    categoryData.splice(0, categoryData.length, ...response.data)
  } else {
    console.log('获取分类信息失败', response.message)
  }
  const resTag = await reqHasTag()
  if (resTag.code == 200) {
    // 将返回的data赋值给tagData
    Object.assign(tagData, resTag.data)
  } else {
    console.log('获取标签信息失败', resTag.message)
  }
})

//获取el-form组件实例
let formRef = ref()

const toolbars = [
  'bold',
  'underline',
  'italic',
  '-',
  'title',
  'strikeThrough',
  'sub',
  'sup',
  'quote',
  'unorderedList',
  'orderedList',
  'task',
  '-',
  'codeRow',
  'code',
  'link',
  'image',
  'table',
  'mermaid',
  'katex',
  '-',
  'revoke',
  'next',
  'save',
  '=',
  'pageFullscreen',
  'fullscreen',
  'preview',
  'htmlPreview',
  'catalog',
]

// 处理标签添加
const handleAddTag = () => {
  is_addTag.value = false // 切换到选择器状态
}

// 处理标签选择
const handleTagChange = () => {
  if (selectedTag.value !== null) {
    // 判断标签是否已经存在于 tags 数组中
    if (ArticleParams.tags.includes(selectedTag.value)) {
      // 提示标签重复
      ElMessage.warning('标签重复，请选择其他标签')
    } else {
      // 将选中的标签添加到 tags 数组中
      ArticleParams.tags.push(selectedTag.value)
      selectedTag.value = null // 清空选中的标签
      is_addTag.value = true // 切换回按钮状态
    }
  }
}

// 获取标签名称
const getTagName = (tagId: number) => {
  const tag = tagData.find((t) => t.id === tagId)
  return tag ? tag.name : ''
}

// 处理标签删除
const handleTagClose = (tag: number) => {
  const index = ArticleParams.tags.indexOf(tag)
  if (index !== -1) {
    ArticleParams.tags.splice(index, 1)
  }
}

//上传文章图片的函数
const onUploadArticleImg = async (files: any, callback: any) => {
  try {
    const res = await Promise.all(
      files.map((file: any) => {
        return new Promise((rev, rej) => {
          const form = new FormData()
          form.append('file', file)
          reqUploadImage(form)
            .then((res) => {
              if (res.code == 200) {
                rev(res.data)
              } else {
                rej(new Error(`Upload failed with code ${res.code}`))
              }
            })
            .catch((error) => rej(error))
        })
      }),
    )
    // 打印结果以进行调试
    console.log(res)
    // 调用回调函数
    callback(res)
  } catch (error) {
    console.error('Error uploading images:', error)
    // 处理错误，例如显示错误消息
  }
}

const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
  //在图片上传成功之前触发，在上传文件之前可以约束文件类型与大小
  //要求：上传文件格式png|jpg|gif <4MB
  if (
    rawFile.type == 'image/png' ||
    rawFile.type == 'image/jpg' ||
    rawFile.type == 'image/jpeg' ||
    rawFile.type == 'image/gif'
  ) {
    if (rawFile.size / 1024 / 1024 < 4) {
      return true
    } else {
      ElMessage({
        type: 'error',
        message: '上传文件大小限制：4MB',
      })
      return false
    }
  } else {
    ElMessage({
      type: 'error',
      message: '上传文件格式限定 png | jpg | jpeg | gif ',
    })
    return false
  }
}

//上传文件成功的钩子
const handleAvatarSuccess: UploadProps['onSuccess'] = (response) => {
  ArticleParams.cover_image = response.data
  ElMessage({
    type: 'success',
    message: '图片上传成功！',
  })
  formRef.value.clearValidate('image')
}

//失败的钩子
const handleAvatarError: UploadProps['onError'] = (response) => {
  ElMessage({
    type: 'error',
    message: '图片上传失败！请修改文件名避免重名',
  })
}

//发布按钮的回调函数
const handlePulish = async () => {
  if (!ArticleParams.title) {
    ElMessage({
      type: 'error',
      message: '文章标题不能为空！',
    })
    return
  }
  if (!ArticleParams.cover_image) {
    ElMessage({
      type: 'error',
      message: '封面图片不能为空！',
    })
    return
  }
  if (!ArticleParams.category) {
    ElMessage({
      type: 'error',
      message: '文章分类不能为空！',
    })
    return
  }
  if (ArticleParams.tags.length === 0) {
    ElMessage({
      type: 'error',
      message: '文章标签不能为空！',
    })
    return
  }
  if (!ArticleParams.content) {
    ElMessage({
      type: 'error',
      message: '文章内容不能为空！',
    })
    return
  }
  const res = await reqAddArticle(ArticleParams)
  if (res.code == 200) {
    ElMessage({
      type: 'success',
      message: '文章发布成功！',
    })
    //置空
    ArticleParams.title = ''
    ArticleParams.cover_image = ''
    ArticleParams.category = ''
    ArticleParams.tags = []
    ArticleParams.content = ''
  } else {
    ElMessage({
      type: 'error',
      message: '文章发布失败！',
    })
  }
}
</script>
<style lang="scss" scoped>
.avatar-uploader .el-upload {
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: var(--el-transition-duration-fast);
}

.avatar-uploader .el-upload:hover {
  border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  text-align: center;
}
</style>
